using System;
using System.Collections.Generic;
using System.Web.UI;

namespace MvpFramework
{
    /// <summary>
    /// A <see cref="ValidationManager"/> for MvpPages
    /// </summary>
    public class PageValidationManager : ValidationManager
    {
        private readonly MvpPage page;
        private readonly List<ValidationMessage> validationErrorLabels = new List<ValidationMessage>();

        /// <summary>
        /// Populates the ErrorLabels for the page
        /// </summary>
        /// <param name="page"></param>
        public PageValidationManager(MvpPage page)
        {
            this.page = page;
            page.PreRender += HideValidationMessagesOnInitialLoad;
        }

        /// <summary>
        /// The Function that will find the <see cref="IValidationMessage"/> from the list of All Validations
        /// </summary>
        public override Func<object, IValidationMessage> FindLabelFunction
        {
            get
            {
                PopulateValidationErrorLabels(page);
                return o => validationErrorLabels.Find(v => v.SpecificationType == o.GetType());
            }
        }

        private void HideValidationMessagesOnInitialLoad(object sender, EventArgs e)
        {
            if (!page.IsInitialLoad)
            {
                return;
            }
            PopulateValidationErrorLabels(page);
            validationErrorLabels.ForEach(v => v.Visible = false);
        }

        /// <summary>
        /// Should return All Validation Labels for a Widget
        /// </summary>
        /// <returns></returns>
        public override IList<IValidationMessage> GetAllValidationLabels()
        {
            return validationErrorLabels.ToArray();
        }

        private void PopulateValidationErrorLabels(Control control)
        {
            foreach (Control childControl in control.Controls)
            {
                if ((childControl is ValidationMessage))
                {
                    validationErrorLabels.Add((ValidationMessage) childControl);
                }

                if (childControl.HasControls()) PopulateValidationErrorLabels(childControl);
            }
        }
    }
}